import { User, IUser } from '../models/user'
import {
  DatabaseError,
  NotFoundError,
  ValidationError,
  AuthenticationError
} from '../errors/CustomError'
import { isMongoError } from '../errors/MongoError'
import { signToken } from '../utils/jwtToken'
import dayjs from 'dayjs'

export class UserService {
  // 创建用户
  async createUser(userData: Partial<IUser>): Promise<IUser> {
    try {
      const user = new User(userData)
      return await user.save()
    } catch (error) {
      if (isMongoError(error) && error.code === 11000) {
        throw new ValidationError('用户名已存在')
      }

      if (error instanceof Error && error.name === 'ValidationError') {
        throw new ValidationError('用户数据验证失败', (error as any).errors)
      }
      throw new DatabaseError('创建用户失败')
    }
  }

  // 用户登录
  async login(
    username: string,
    password: string
  ): Promise<{ success: boolean; message: string; data?: any }> {
    try {
      const user = await User.findOne({ username })

      if (!user) {
        throw new AuthenticationError('用户不存在')
      }

      const isPasswordValid = await user.comparePassword(password)
      if (!isPasswordValid) {
        throw new AuthenticationError('密码错误')
      }

      // 生成JWT token
      const token = signToken({
        id: user.id,
        username: user.username,
        token_created_at: user.updated_at
      })

      // 返回用户信息（不包含密码）
      const userInfo = user.toJSON()
      return { success: true, message: '登录成功', data: { ...userInfo, token } }
    } catch (error) {
      if (error instanceof AuthenticationError) {
        throw error
      }
      throw new DatabaseError('登录过程出错')
    }
  }

  // 删除用户
  async deleteUser(id: string): Promise<boolean> {
    try {
      // 将字符串id转换为数字
      const userId = parseInt(id, 10)

      if (isNaN(userId)) {
        throw new ValidationError('无效的用户ID')
      }

      const result = await User.findOneAndDelete({ id: userId })

      if (!result) {
        throw new NotFoundError('用户不存在')
      }

      return true
    } catch (error) {
      if (error instanceof NotFoundError || error instanceof ValidationError) {
        throw error
      }
      throw new DatabaseError('删除用户失败')
    }
  }

  // 更新用户信息
  async updateUser(
    id: string,
    updateData: Partial<IUser>
  ): Promise<IUser | null> {
    try {
      // 将字符串id转换为数字
      const userId = parseInt(id, 10)

      if (isNaN(userId)) {
        throw new ValidationError('无效的用户ID')
      }

      // 移除密码字段以防止通过此方法更新密码
      const { password, ...updateFields } = updateData

      // // 检查是否包含敏感字段，如果有则需要更新updated_at使token失效
      // const sensitiveFields = ['role', 'status']
      // const hasSensitiveFields = Object.keys(updateFields).some(field => 
      //   sensitiveFields.includes(field)
      // );

      // // 如果包含敏感字段，则手动添加updated_at字段
      // if (hasSensitiveFields) {
      //   updateFields.updated_at = dayjs().format('YYYY-MM-DD HH:mm:ss')
      // }

      const user = await User.findOneAndUpdate({ id: userId }, updateFields, {
        new: true
      })

      if (!user) {
        throw new NotFoundError('用户不存在')
      }

      return user
    } catch (error) {
      if (error instanceof NotFoundError || error instanceof ValidationError) {
        throw error
      }
      if (isMongoError(error) && error.code === 11000) {
        throw new ValidationError('用户名已存在')
      }
      if (error instanceof Error && error.name === 'ValidationError') {
        throw new ValidationError('用户数据验证失败', (error as any).errors)
      }
      throw new DatabaseError('更新用户信息失败')
    }
  }

  // 重置密码
  async resetPassword(
    id: string,
    newPassword: string
  ): Promise<{ success: boolean; message: string }> {
    try {
      // 验证密码强度
      if (newPassword.length < 6) {
        throw new ValidationError('密码长度不能少于6位')
      }

      // 将字符串id转换为数字
      const userId = parseInt(id, 10)

      if (isNaN(userId)) {
        throw new ValidationError('无效的用户ID')
      }

      // 重置密码时同时更新updated_at字段，使所有token失效
      const updateData = {
        password: newPassword,
        updated_at: dayjs().format('YYYY-MM-DD HH:mm:ss')
      };

      const user = await User.findOneAndUpdate(
        { id: userId },
        updateData,
        { new: true }
      )

      if (!user) {
        throw new NotFoundError('用户不存在')
      }

      return { success: true, message: '密码重置成功' }
    } catch (error) {
      if (error instanceof ValidationError || error instanceof NotFoundError) {
        throw error
      }
      throw new DatabaseError('密码重置失败')
    }
  }

  // 获取用户
  async findAll(query: any = {}): Promise<{ list: IUser[]; total: number }> {
    try {
      const page = Math.max(Number(query.page) || 1, 1)
      const size = Math.max(Number(query.size) || 10, 1)
      const type = query.type?.toString() || ''

      const skip = (page - 1) * size
      const filter: any = {}

      // 模糊匹配条件
      if (query.username) {
        filter.username = { $regex: query.username, $options: 'i' }
      }

      // 根据查询条件计算总数
      const total = await User.countDocuments(filter)

      if (type === 'all') {
        const list = await User.find(filter)
        return {
          list,
          total
        }
      }

      const list = await User.find(filter).skip(skip).limit(size)
      return {
        list,
        total
      }
    } catch (error) {
      throw new DatabaseError('查询用户列表失败')
    }
  }

  // 根据ID获取用户
  async getUserById(id: string): Promise<IUser | null> {
    try {
      // 将字符串id转换为数字
      const userId = parseInt(id, 10)

      if (isNaN(userId)) {
        throw new ValidationError('无效的用户ID')
      }

      // 使用 id 字段查询
      const user = await User.findOne({ id: userId }, { password: 0 })
    console.log(user)

      return user
    } catch (error) {
      if (error instanceof NotFoundError || error instanceof ValidationError) {
        throw error
      }
      throw new DatabaseError('获取用户失败')
    }
  }

  // 检查用户名是否存在
  async checkUsernameExists(username: string): Promise<boolean> {
    try {
      const user = await User.findOne({ username })
      return !!user
    } catch (error) {
      throw new DatabaseError('查询用户名失败')
    }
  }
}

export const userService = new UserService()
